<?php

declare(strict_types=1);
/**
 * This file is part of MoChat.
 * @link     https://mo.chat
 * @document https://mochat.wiki
 * @contact  group@mo.chat
 * @license  https://github.com/mochat-cloud/mochat/blob/master/LICENSE
 */
namespace MoChat\App\WorkEmployee\Logic;

use Hyperf\Di\Annotation\Inject;
use MoChat\App\Corp\Contract\CorpContract;
use MoChat\App\Rbac\Contract\RbacRoleContract;
use MoChat\App\Rbac\Contract\RbacUserRoleContract;
use MoChat\App\Tenant\Contract\TenantContract;
use MoChat\App\User\Contract\UserContract;
use MoChat\App\WorkContact\Contract\WorkContactEmployeeContract;
use MoChat\App\WorkDepartment\Contract\WorkDepartmentContract;
use MoChat\App\WorkEmployee\Constants\ContactAuth;
use MoChat\App\WorkEmployee\Constants\Gender;
use MoChat\App\WorkEmployee\Constants\Status as EmployeeStatus;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeDepartmentContract;
use MoChat\App\WorkEmployee\Contract\WorkEmployeeStatisticContract;

/**
 * 成员管理-列表.
 *
 * Class IndexLogic
 */
class IndexLogic
{
    /**
     * @Inject
     * @var WorkEmployeeContract
     */
    protected $workEmployeeService;

    /**
     * @Inject
     * @var WorkEmployeeStatisticContract
     */
    protected $workEmployeeStatisticService;

    /**
     * @Inject
     * @var UserContract
     */
    protected $userService;

    /**
     * @Inject
     * @var RbacUserRoleContract
     */
    protected $rbacUserRoleService;

    /**
     * @Inject
     * @var RbacRoleContract
     */
    protected $rbacRoleService;

    /**
     * @Inject
     * @var WorkEmployeeDepartmentContract
     */
    protected $workEmployeeDepartmentService;

    /**
     * @Inject
     * @var WorkContactEmployeeContract
     */
    protected $workContactEmployeeService;

    /**
     * @Inject
     * @var WorkDepartmentContract
     */
    protected $workDepartmentService;

    /**
     * @Inject
     * @var CorpContract
     */
    protected $corpService;

    /**
     * @Inject
     * @var TenantContract
     */
    protected $tenantService;

    /**
     * 成员列表.
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function handle(array $params): array
    {
        $corpId = (int) $params['user']['corpIds'][0];

        // 组织响应数据
        $data = [
            'page' => [
                'page' => $params['page'],
                'perPage' => $params['perPage'],
                'total' => 0,
                'totalPage' => 0,
            ],
            'list' => [],
            'tenant' => [
                'maxEmployee' => 0,
                'useEmployee' => 0,
                'notUseEmployee' => 0,
                'expiredAt' => '',
            ],
        ];

        $corp = $this->corpService->getCorpById($corpId, ['tenant_id']);
        if (empty($corp)) {
            return $data;
        }

        $tenant = $this->tenantService->getTenantById($corp['tenantId']);
        if (empty($tenant)) {
            return $data;
        }

        $useEmployee = $this->workEmployeeService->countOpenedWorkEmployeeByCorpId($corpId);

        $data['tenant'] = [
            'maxEmployee' => (int) $tenant['maxEmployee'],
            'useEmployee' => $useEmployee,
            'notUseEmployee' => (int) $tenant['maxEmployee'] - $useEmployee,
            'expiredAt' => $tenant['expiredAt'],
        ];

        // 查询成员基本信息
        $employeeData = $this->getEmployee($params);
        if (empty($employeeData['data'])) {
            return $data;
        }
        $data['page'] = [
            'page' => $params['page'],
            'perPage' => $params['perPage'],
            'total' => ! empty($employeeData['total']) ? $employeeData['total'] : 0,
            'totalPage' => ! empty($employeeData['last_page']) ? $employeeData['last_page'] : 0,
        ];

        // 客户统计数据
//        $employeeStatistics = $this->getEmployeeStatistics($employeeIds);
        // 获取用户的角色信息
        $userRoleList = $this->getUserRoleList(array_column($employeeData['data'], 'logUserId'));

        foreach ($employeeData['data'] as $key => $employee) {
            // 状态
//            $employeeData['data'][$key]['statusName'] = EmployeeStatus::getMessage($employee['status']);
            // 性别
            $employeeData['data'][$key]['gender'] = Gender::getMessage($employee['gender']);
            // 头像
            $employeeData['data'][$key]['thumbAvatar'] = $employee['thumbAvatar'] ? file_full_url($employee['thumbAvatar']) : '';
            // 外部联系人
            $employeeData['data'][$key]['contactAuthName'] = ContactAuth::getMessage($employee['contactAuth']);

            // 用户id
            $employeeData['data'][$key]['userId'] = $employee['logUserId'];

            // 角色名称
            $employeeData['data'][$key]['roleName'] = isset($userRoleList[$employee['logUserId']]) ? $userRoleList[$employee['logUserId']]['roleName'] : '';

            // 角色id
            $employeeData['data'][$key]['roleId'] = isset($userRoleList[$employee['logUserId']]) ? $userRoleList[$employee['logUserId']]['roleId'] : 0;

            // 部门
            $employeeData['data'][$key]['department'] = $this->getDepartmentList((int) $employee['logUserId'], $corpId);

            // 客户数量
            $employeeData['data'][$key]['contactCount'] = $this->workContactEmployeeService->countWorkContactEmployeesByEmployeeIdCorpId($employee['id'], $corpId);

            $user=$this->userService->getUserById($employee['logUserId'], ['extn','phone']);
            //分机号
            $employeeData['data'][$key]['extn'] = $user['extn'] ?? '';
            $employeeData['data'][$key]['mobile'] = $employeeData['data'][$key]['mobile']?:($user['phone']??'');
        }
        $data['list'] = $employeeData['data'];
        return $data;
    }

    /**
     * 成员基础信息.
     */
    protected function getEmployee(array $params): array
    {
        // 搜索条件
        $options = [
            'page' => $params['page'],
            'perPage' => $params['perPage'],
            'orderByRaw' => 'created_at desc',
        ];

        // 判断权限是否为全公司
//        if ($params['user']['isRoot'] === 1) {
//            $where[] = ['corp_id', '=', $params['user']['corpIds'][0]];
//        } else if (! empty($params['user']['deptEmployeeIds'])) {
//            $where[] = ['id', 'IN',  $params['user']['deptEmployeeIds']];
//        } else {
//            $where[] = ['id', '=', $params['user']['workEmployeeId']];
//        }

        // 权限暂时修改为查看全公司
        $where[] = ['corp_id', '=', $params['user']['corpIds'][0]];

        if (! empty($params['name'])) {
            $where[] = ['name', 'LIKE', '%' . $params['name'] . '%'];
        }

        if (! empty($params['mobile'])) {
            $where[] = ['mobile', 'LIKE', '%' . $params['mobile'] . '%'];
        }

        // 席位状态 1：正常，3：未开通
        if (! empty($params['status'])) {
            $where[] = ['auth_status', '=', $params['status']];
        }

        // 部门
        if (! empty($params['departmentId'])) {
            $employeeIds = $this->getDepartmentEmployeeIds((int) $params['departmentId']);
            if (empty($employeeIds)) {
                $employeeData['data'] = [];
                return $employeeData;
            }
            $where[] = ['id', 'IN', $employeeIds];
        }

        // 角色查询
        if (! empty($params['roleId'])) {
            $roleEmployee = $this->rbacUserRoleService->getRbacUserRolesByRoleId((int) $params['roleId'], ['user_id']);
            if (empty($roleEmployee)) {
                $employeeData['data'] = [];
                return $employeeData;
            }
            $ids = array_unique(array_column($roleEmployee, 'userId'));
            $where[] = ['log_user_id', 'IN', $ids];
        }

        $list = $this->workEmployeeService->getWorkEmployeeList(
            $where,
            ['id', 'name', 'mobile', 'thumb_avatar', 'status', 'contact_auth', 'wx_user_id', 'log_user_id', 'corp_id', 'gender', 'auth_status'],
            $options
        );
        foreach ($list['data'] as &$item) {
            $userInfo = $this->userService->getUserById($item['logUserId'], ['status']);
            if (! empty($userInfo)) {
                $item['authStatus'] = $userInfo['status'] === 1 ? $item['authStatus'] : 3;
            }
        }
        // 员工基础信息
        return $list;
    }

    public function getDepartmentEmployeeIds(int $departmentId): array
    {
        // 所有部门id
        $departmentIds = $this->recursion($departmentId, [$departmentId]);
        // 部门员工
        $departmentEmployees = $this->workEmployeeDepartmentService->getWorkEmployeeDepartmentsByDepartmentIds($departmentIds, ['employee_id']);
        if (empty($departmentEmployees)) {
            return [];
        }
        return array_unique(array_column($departmentEmployees, 'employeeId'));
    }

    /**
     * 成员统计
     */
    protected function getEmployeeStatistics(array $employeeIds): array
    {
        $employeeStatisticsIds = $this->workEmployeeStatisticService->getEmployeeStatisticIdsByEmployeeIds($employeeIds, ['employee_id'], ['groupBy' => ['employee_id']]);
        if (empty($employeeStatisticsIds)) {
            return [];
        }
        foreach ($employeeStatisticsIds as $esk => $esv) {
            $statisticIds[] = $esv['id'];
        }
        $employeeStatisticsData = $this->workEmployeeStatisticService->getWorkEmployeeStatisticsById($statisticIds);
        if (empty($employeeStatisticsData)) {
            return [];
        }
        $employeeStatistics = [];
        foreach ($employeeStatisticsData as $esk => $esv) {
            $employeeStatistics[$esv['employeeId']] = $esv;
        }
        unset($employeeStatisticsIds, $employeeStatisticsData);
        return $employeeStatistics;
    }

    /**
     * 无限递归查询.
     */
    private function recursion(int $id, array $ids): array
    {
        // 子部门信息
        $childDepartment = $this->workDepartmentService->getWorkDepartmentsByParentId($id, ['id']);
        if (count($childDepartment) > 0) {
            $childIds = array_column($childDepartment, 'id');
            $ids = array_merge($ids, $childIds);
        }
        // 处理子部门
        foreach ($childDepartment as &$v) {
            $ids = $this->recursion($v['id'], $ids);
        }
        unset($v);
        return $ids;
    }

    /**
     * @param array $userIdArr 用户ID数组
     * @return array 响应数组
     */
    private function getUserRoleList(array $userIdArr): array
    {
        $userRoleList = $this->rbacUserRoleService->getRbacUserRolesByUserId($userIdArr, ['id', 'user_id', 'role_id']);
        if (empty($userRoleList)) {
            return [];
        }
        $roleIdArr = array_unique(array_column($userRoleList, 'roleId'));
        $roleList = $this->rbacRoleService->getRbacRolesById($roleIdArr, ['id', 'name']);
        if (empty($roleList)) {
            return [];
        }
        $roleList = array_column($roleList, 'name', 'id');
        $userRoleList = array_map(function ($userRole) use ($roleList) {
            return [
                'userId' => $userRole['userId'],
                'roleId' => $userRole['roleId'],
                'roleName' => isset($roleList[$userRole['roleId']]) ? $roleList[$userRole['roleId']] : '',
            ];
        }, $userRoleList);

        return array_column($userRoleList, null, 'userId');
    }

    /**
     * @param int $userId 用户ID
     * @param int $corpId 企业ID
     * @return array 响应数组
     */
    private function getDepartmentList(int $userId, int $corpId): array
    {
        $employee = $this->workEmployeeService->getWorkEmployeeByCorpIdLogUserId($corpId, $userId, ['id']);
        if (empty($employee)) {
            return [];
        }
        $employeeDepartments = $this->workEmployeeDepartmentService->getWorkEmployeeDepartmentsByEmployeeId((int) $employee['id'], ['department_id']);
        if (empty($employeeDepartments)) {
            return [];
        }
        $departmentIdArr = array_column($employeeDepartments, 'departmentId');
        $departmentList = $this->workDepartmentService->getWorkDepartmentsById($departmentIdArr, ['id', 'name']);
        return empty($departmentList) ? [] : array_map(function ($department) {
            return [
                'departmentId' => $department['id'],
                'departmentName' => $department['name'],
            ];
        }, $departmentList);
    }

    // 旧版数据，暂时保存
    private function old(): array
    {
//        foreach ($employeeData['data'] as $key => $employee) {
//            // 成员总聊天数量
//            $employeeData['data'][$key]['messageNums'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['chatCnt'])) {
//                $employeeData['data'][$key]['messageNums'] = $employeeStatistics[$employee['id']]['chatCnt'];
//            }
//            // 成员发送消息数量
//            $employeeData['data'][$key]['sendMessageNums'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['messageCnt'])) {
//                $employeeData['data'][$key]['sendMessageNums'] = $employeeStatistics[$employee['id']]['messageCnt'];
//            }
//            // 已回复聊天占比
//            $employeeData['data'][$key]['replyMessageRatio'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['replyPercentage'])) {
//                $employeeData['data'][$key]['replyMessageRatio'] = bcdiv((string) $employeeStatistics[$employee['id']]['replyPercentage'], '100', 2);
//            }
//            // 新增客户数
//            $employeeData['data'][$key]['addNums'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['newContactCnt'])) {
//                $employeeData['data'][$key]['addNums'] = $employeeStatistics[$employee['id']]['newContactCnt'];
//            }
//            // 发起申请数
//            $employeeData['data'][$key]['applyNums'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['newApplyCnt'])) {
//                $employeeData['data'][$key]['applyNums'] = $employeeStatistics[$employee['id']]['newApplyCnt'];
//            }
//            // 删除/拉黑客户数
//            $employeeData['data'][$key]['invalidContact'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['negativeFeedbackCnt'])) {
//                $employeeData['data'][$key]['invalidContact'] = $employeeStatistics[$employee['id']]['negativeFeedbackCnt'];
//            }
//            // 平均首次回复时长
//            $employeeData['data'][$key]['averageReply'] = 0;
//            if (! empty($employeeStatistics[$employee['id']]['avgReplyTime'])) {
//                $employeeData['data'][$key]['averageReply'] = $employeeStatistics[$employee['id']]['avgReplyTime'];
//            }
        // 状态
//            $employeeData['data'][$key]['statusName'] = EmployeeStatus::getMessage($employee['status']);
//        }
    }
}
